#ifndef __MCS__BLOCK__HPP
#define __MCS__BLOCK__HPP

#include "Element.hpp"

class Variable;
class Program;
class FunctionFactory;

class Block : public Element
{
public:
	Block(SourceLocation const & location);
	~Block();

	virtual void init(Block * parentBlock);
	void appendElement(ptr<Element> elem);
	void initAsRoot(Program * program);

	void registerVariableDeclaration(ptr<Variable> var);
	void registerBlock(ptr<Block> block);
	ptr<Variable> resolveVariable(String const & name) const;

	virtual void execute() const;
	virtual ptr<Element> concat(ptr<Element> other);

	void registerVariableForCleanup(ptr<Variable> var) const;
	
	std::ostream & outputStream() const;
	FunctionFactory * functionFactory() const;
private:
	typedef std::map< String, ptr<Variable> > VariableMap;
	std::vector< ptr<Element> > elements_;
	std::vector< ptr<Block> > blocks_;
	VariableMap varMap_;
	mutable std::vector< ptr<Variable> > vars_;
	Program * program_;
	
	void checkVariables(VariableMap const & vars);
};

#endif //__MCS__BLOCK__HPP
